package com.agv.core.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import com.agv.core.dao.dataExtractor.ModuloResultSetExtractor;
import com.agv.core.dao.dataExtractor.UserResultSetExtractor;
import com.agv.core.exception.SecurityException;
import com.agv.core.objectDomain.Modulo;
import com.agv.core.objectDomain.Usuario;

public class SecurityDAOImpl implements ISecurityDAO {

	private JdbcTemplate jdbcTemplate;

	public Usuario login(String cdkey, String pwPAssword)
			throws SecurityException {
		try {
			Usuario usuario = (Usuario) jdbcTemplate.query(BUSCAR_USUARIO,
					new Object[] { cdkey }, new UserResultSetExtractor());
			return usuario;
		} catch (Exception e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		}
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Modulo> obtenerModulos(Usuario usuario)
			throws SecurityException {
		ArrayList<Modulo> modulos = (ArrayList<Modulo>) jdbcTemplate.query(
				BUSCAR_MODULOS_POR_USUARIO, new Object[] { usuario.getPerfil()
						.getIdPerfil() }, new ModuloResultSetExtractor());
		return modulos;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Modulo> obtenerFuncionesPorModulo()
			throws SecurityException {
		ArrayList<Modulo> modulos = (ArrayList<Modulo>) jdbcTemplate.query(
				BUSCAR_FUNCIONES_POR_MODULO, new ModuloResultSetExtractor());
		return modulos;
	}

	public String obtieneCdAcceso(Integer idUsuario) throws SecurityException {
		return (String) jdbcTemplate.queryForObject(OBTIENE_CD_PRIMER_ACCESO,
				new Object[] { idUsuario }, String.class);
	}

	public void actualizaContrasenia(String pwContrasenia, Integer idUsuario)
			throws SecurityException {
		jdbcTemplate.update(ACTUALIZA_CONTRASENIA, new Object[] {
				pwContrasenia, idUsuario });
		jdbcTemplate.update(ACTUALIZAR_ULTIMO_ACCESO,
				new Object[] { idUsuario });
	}

	public void insertaCdPrimerAcceso(String cdPrimerAcceso, String nbMail)
			throws SecurityException {
		jdbcTemplate.update(INSERTA_CD_PRIMER_ACCESO, new Object[] {
				cdPrimerAcceso, nbMail });
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	private final String OBTIENE_CD_PRIMER_ACCESO = "select cd_primeracceso from empresa.emp006_cfg_usuarios where id_usuario = ?";

	private final String INSERTA_CD_PRIMER_ACCESO = "update empresa.emp006_cfg_usuarios set cd_primeracceso = ? where nb_mail = ?";

	private final String ACTUALIZA_CONTRASENIA = "update empresa.emp006_cfg_usuarios set pw_contra = ? where id_usuario = ?";

	private final String BUSCAR_USUARIO = "select eu.id_usuario,eu.nb_usuario,eu.nb_mail,eu.nb_depto,eu.pw_contra,eu.tm_ultimo_acceso,"
			+ " eu.id_org,eo.nb_org,eu.id_perfil, ep.tp_perfil, ep.st_perfil from empresa.emp006_cfg_usuarios eu, empresa.emp008_perfil ep, "
			+ " empresa.emp005_cfg_organizacion eo where eu.cd_usuario = ? and eu.id_perfil = ep.id_perfil and eo.id_org = eu.id_org";

	private final String BUSCAR_MODULOS_POR_USUARIO = "select ef.id_funcion,ef.nb_funcion,ef.nb_icon as snb_icon,ef.id_modulo,"
			+ " em.nb_modulo,ef.id_submodulo,esm.nb_submodulo, em.nb_icon as nb_micon, ef.nb_class, "
			+ " esm.nb_icon, ef.nb_ruta from empresa.emp010_funcion ef, empresa.emp012_modulo em, empresa.emp013_submodulo esm, "
			+ " empresa.emp009_perfil_funcion epf where ef.id_modulo = em.id_modulo and ef.id_modulo = esm.id_modulo "
			+ " and ef.id_submodulo = esm.id_submodulo and ef.id_funcion = ANY (epf.cd_funcion) and epf.id_perfil = ? order by 1 ";

	private final String BUSCAR_FUNCIONES_POR_MODULO = "select ef.id_funcion,ef.nb_funcion,ef.id_modulo,ef.id_submodulo,"
			+ " em.nb_modulo,esm.nb_submodulo,esm.nb_icon,ef.nb_ruta"
			+ " from empresa.emp010_funcion ef, empresa.emp012_modulo em, empresa.emp013_submodulo esm where em.id_modulo = ef.id_modulo "
			+ " and esm.id_submodulo = ef.id_submodulo and esm.id_modulo = ef.id_modulo order by 3,5,1";

	private final String ACTUALIZAR_ULTIMO_ACCESO = "update empresa.emp006_cfg_usuarios set tm_ultimo_acceso = (select now()) where id_usuario = ?";

	private final String INSERTAR_PERFIL = "insert into empresa.emp008_perfil (id_perfil,tp_perfil,st_perfil) "
			+ " values (?,?,?)";

	private String INSERTAR_PERFIL_FUNCION = "insert into empresa.emp009_perfil_funcion (id_perfil,cd_funcion) "
			+ " values ";

	private final String CONSULTA_SEC_PERFIL = "select nextval('empresa.emp008_perfil_seq')";

	public void actualizarUltimoAcceso(Usuario usuario)
			throws SecurityException {
		jdbcTemplate.update(ACTUALIZAR_ULTIMO_ACCESO, new Object[] { usuario
				.getIdUsuario() });
	}

	public void insertaPerfil(final String nbPerfil, final Integer stEstatus,
			String[] idFunciones) throws SecurityException {

		Integer idPerfil = jdbcTemplate.queryForInt(CONSULTA_SEC_PERFIL);

		int res = jdbcTemplate.update(INSERTAR_PERFIL, new Object[] { idPerfil,
				nbPerfil, stEstatus });

		String exp = "'{";
		for (String idFuncion : idFunciones) {
			exp += idFuncion + ",";
		}
		exp = exp.substring(0, exp.length() - 1);
		exp += "}'";

		INSERTAR_PERFIL_FUNCION += "(" + idPerfil + "," + exp + ")";
		res = jdbcTemplate.update(INSERTAR_PERFIL_FUNCION);
	}
}
